package com.google.code.jholidays.events;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.util.Calendar;
import java.util.Date;

import org.junit.Test;

import com.google.code.jholidays.core.EventDescriptor;
import com.google.code.jholidays.events.FixedEvent;
import com.google.code.jholidays.events.parameters.DayMonthPair;
import com.google.code.jholidays.events.properties.FixedEventProperties;


public class FixedEventTest {

    @Test(expected = IllegalArgumentException.class)
    public void testNullProperties() {
	FixedEvent event = new FixedEvent(null);
	assertNull(event);
    }

    @Test
    public void testFixedEvent() {
	DayMonthPair pair = new DayMonthPair(1, 1);
	EventDescriptor descriptor = new EventDescriptor(1);
	FixedEventProperties props = new FixedEventProperties(descriptor, pair);
	FixedEvent event = new FixedEvent(props);
	assertNotNull(event);

	// verify fields
	assertSame(event.getDescriptor(), descriptor);
	assertSame(event.getParent(), null);
	assertSame(event.getDayMonth(), pair);
    }

    @Test
    public void testGetDate() {

	// create events for each day in current year and test it's
	// getDate() for +/- delta years

	EventDescriptor descriptor = new EventDescriptor(1);
	final int delta = 5;

	Calendar c = Calendar.getInstance();

	int minDay = c.getActualMinimum(Calendar.DAY_OF_YEAR);
	int maxDay = c.getActualMaximum(Calendar.DAY_OF_YEAR);

	c.set(Calendar.DAY_OF_YEAR, minDay);

	int currentDay = minDay;

	while (currentDay <= maxDay) {
	    int month = c.get(Calendar.MONTH) + 1;
	    int day = c.get(Calendar.DATE);

	    DayMonthPair pair = new DayMonthPair(day, month);

	    FixedEventProperties props = new FixedEventProperties(descriptor,
		    pair);

	    FixedEvent event = new FixedEvent(props);
	    assertVerifyEvent(event, delta, c.get(Calendar.YEAR));

	    ++currentDay;
	    c.set(Calendar.DAY_OF_YEAR, currentDay);

	}
    }

    protected void assertVerifyEvent(FixedEvent event, int delta,
	    int currentYear) {
	assertNotNull(event);
	assertTrue(delta >= 0);

	Calendar c = Calendar.getInstance();

	final int min = currentYear - delta;
	final int max = currentYear + delta;

	DayMonthPair pair = event.getDayMonth();

	for (int i = min; i <= max; ++i) {
	    Date date = event.getDate(i);
	    c.setTime(date);

	    assertEquals(c.get(Calendar.DATE), pair.getDay());
	    assertEquals(c.get(Calendar.MONTH) + 1, pair.getMonth());
	    assertEquals(c.get(Calendar.YEAR), i);
	}
    }
}
